package com.ymt.bpm.sso;

import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.ymt.spi.webserver.tomcat.realm.LoginConst;
import com.ymt.spi.webserver.tomcat.realm.TenantPrincipal;

/**

 * @ClassName: SecurityFilter
 * @Description: 用户安全认证的过滤器
 * @author Johnny
 * @date 2015-12-24 下午2:15:21
 */
public class SecurityFilter implements Filter {
	
	/**
	 * logger.
	 */
	private Logger logger = Logger.getLogger(this.getClass().getName());
	
    /**
     * destroy.
     */
    public void destroy() {
    	
    }

    /**
     * @MethodName: doFilter
     * @Description: 检查用户是否已认证
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, 
    		ServletResponse response,
            FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;
        
        //登录页面地址
        //String loginPath = req.getContextPath() + LoginConst.LOGIN_PAGE;
        String loginPath = req.getContextPath();
        if (loginPath==null || loginPath.length()==0) {
        	loginPath = "/";
		}
        
        if (logger.isLoggable(Level.FINER)) {
        	logger.finer("doFilter loginPath=" + loginPath);
        	logger.finer("doFilter request path=" + req.getRequestURI());
        }
        //get session
        HttpSession session = req.getSession(true);
        
        //get login user
        TenantPrincipal principal = (TenantPrincipal) req.getUserPrincipal();
        //如果未认证，跳转到登录页面
        if (principal==null || principal.getName()==null || session==null) {
        	res.sendRedirect(loginPath);
        	logger.finer("doFilter principal is null");
        	return;
        }
        
        if (logger.isLoggable(Level.FINER)) {
        	logger.finer("doFilter principal.getName()=" + principal.getName());
        	logger.finer("doFilter principal.getDisplayName()=" + principal.getDisplayName());
        	//logger.finer("doFilter principal.getPassword()=" + principal.getPassword());
        	logger.finer("doFilter principal.getTenantId()=" + principal.getTenantId());
        	logger.finer("doFilter principal.getJaasRoles()=" + principal.getJaasRoles());
        	logger.finer("doFilter principal.getBizRoles()=" + principal.getBizRoles());
        }
        
        try {
            
            /**
             * Judge JAAS Authentication Result
             */
            if (session.getAttribute(LoginConst.LOGINNAME)==null) {//用户已认证但session信息为空
				logger.finer("doFilter loginName is not in session.");
            	//获取用户信息服务类
            	session.setAttribute(LoginConst.LOGINNAME, principal.getName());
            	session.setAttribute(LoginConst.DISPLAYNAME, principal.getDisplayName());
            	session.setAttribute(LoginConst.TENANTID, principal.getTenantId());
            	session.setAttribute(LoginConst.USERID, principal.getName());
            	session.setAttribute(LoginConst.LANG, LoginConst.LANG_ZH);
            	session.setAttribute(LoginConst.ROLES, toJSONString(principal.getBizRoles()));
            	//TODO profile
            }
            
        } catch (Exception ex) {
        	//如果认证发生错误，返回登录页面
            ex.printStackTrace(System.out);
            logger.warning("doFilter exception:" + ex.getMessage());
            res.sendRedirect(loginPath);
        }
        
        //继续运行其他过滤器
        filterChain.doFilter(request, response);

    }

    /**
     * init.
     * @param config
     * 
     */
    public void init(FilterConfig config) {
    	logger.info("securityFilter init.");
    }
    
    private String toJSONString(List<String> list) {
    	StringBuilder sb = new StringBuilder("[");
    	if (list!=null && list.size()>0) {
    		for (String s : list) {
    			if (sb.length()>1) sb.append(", ");
    			sb.append("\"");
    			sb.append(s);
    			sb.append("\"");
    		}
    	}
    	sb.append("]");
    	return sb.toString();
    }
    
}
